
    class Endian {
        public static LITTLE_ENDIAN = 0;
        public static BIG_ENDIAN = 1;
    }
    
    class ByteArray{
        public bufferExtSize:number;
        public EOF_byte:number;
        public EOF_code_point:number;
        public write_position:number;
        public data:any;
        private _position:number;
        private _bytes:Uint8Array;
        private _endian:number;
        constructor(buffer:ArrayBuffer=null, bufferExtSize:number=0) {
            if (bufferExtSize === void 0) { bufferExtSize = 0; }
            let s = this;
            s.bufferExtSize = 0; //Buffer expansion size
            s.EOF_byte = -1;
            s.EOF_code_point = -1;
            if (bufferExtSize < 0) {
                bufferExtSize = 0;
            }
            s.bufferExtSize = bufferExtSize;
            let bytes, wpos = 0;
            if (buffer) {
                let uint8 = void 0;
                if (buffer instanceof Uint8Array) {
                    uint8 = buffer;
                    wpos = buffer.length;
                }
                else {
                    wpos = buffer.byteLength;
                    uint8 = new Uint8Array(buffer);
                }
                if (bufferExtSize == 0) {
                    bytes = new Uint8Array(wpos);
                }
                else {
                    var multi = (wpos / bufferExtSize | 0) + 1;
                    bytes = new Uint8Array(multi * bufferExtSize);
                }
                bytes.set(uint8);
            }
            else {
                bytes = new Uint8Array(bufferExtSize);
            }
            s.write_position = wpos;
            s._position = 0;
            s._bytes = bytes;
            s.data = new DataView(bytes.buffer);
            s._endian = Endian.BIG_ENDIAN;
        }
        public set endian(val)
        {let s = this;
            s._endian = val;
        }
        public get endian():number
        {
            return this._endian;
        }
        /**
         * @deprecated
         * @version Egret 2.4
         * @platform Web,Native
         */
        public setArrayBuffer(buffer) {
        }
        public get readAvailable()
        {let s = this;
            return s.write_position - s._position;
        }
        public get buffer():ArrayBuffer
        {let s = this;
            return s.data.buffer.slice(0, s.write_position);
        }
        public set buffer(val:ArrayBuffer)
        {let s = this;
            let wpos = val.byteLength;
            let uint8 = new Uint8Array(val);
            let bufferExtSize = this.bufferExtSize;
            let bytes;
            if (bufferExtSize == 0) {
                bytes = new Uint8Array(wpos);
            }
            else {
                let multi = (wpos / bufferExtSize | 0) + 1;
                bytes = new Uint8Array(multi * bufferExtSize);
            }
            bytes.set(uint8);
            s.write_position = wpos;
            s._bytes = bytes;
            s.data = new DataView(bytes.buffer);
        }
        public get rawBuffer()
        {
            return this.data.buffer;
        }
        public get bytes()
        {
        return this._bytes;
        }
        public get dataView():DataView
        {
            return this.data;
        }
        public set dataView(val:DataView)
        {
            this.buffer = val.buffer;
        }
        public get bufferOffset()
        {
            return this.data.byteOffset;
        }
        public get position()
        {
            return this._position;
        }
        public set position(val)
        {let s = this;
            s._position = val;
            if (val > s.write_position) {
                s.write_position = val;
            }
        }
        public get length()
        {
            return this.write_position;
        }
        private _validateBuffer(value) {let s = this;
            if (s.data.byteLength < value) {
                var be = s.bufferExtSize;
                var tmp;
                if (be == 0) {
                    tmp = new Uint8Array(value);
                }
                else {
                    var nLen = ((value / be >> 0) + 1) * be;
                    tmp = new Uint8Array(nLen);
                }
                tmp.set(s._bytes);
                s._bytes = tmp;
                s.data = new DataView(tmp.buffer);
            }
        }
        public get bytesAvailable()
        {
            return this.data.byteLength - this._position;
        }

        public clear() {
            let s = this;
            let buffer = new ArrayBuffer(s.bufferExtSize);
            s.data = new DataView(buffer);
            s._bytes = new Uint8Array(buffer);
            s._position = 0;
            s.write_position = 0;
        }
        public readBoolean(){let s = this;
            if (s.validate(1 /* SIZE_OF_BOOLEAN */))
                return !!s._bytes[s.position++];
        }

        public readByte() {let s = this;
            if (s.validate(1 /* SIZE_OF_INT8 */))
                return s.data.getInt8(s.position++);
        }
        public readBytes(bytes, offset, length) {let s = this;
            if (offset === void 0) { offset = 0; }
            if (length === void 0) { length = 0; }
            if (!bytes) {
                return;
            }
            var pos = s._position;
            var available = s.write_position - pos;
            if (available < 0) {
                // egret.$error(1025);
                console.log("byteArray_Error:"+1025);
                return;
            }
            if (length == 0) {
                length = available;
            }
            else if (length > available) {
                console.log("byteArray_Error:"+1025);
                return;
            }
            var position = bytes._position;
            bytes._position = 0;
            bytes.validateBuffer(offset + length);
            bytes._position = position;
            bytes._bytes.set(s._bytes.subarray(pos, pos + length), offset);
            s.position += length;
        }
        public readDouble() {let s = this;
            if (s.validate(8 /* SIZE_OF_FLOAT64 */)) {
                var value = s.data.getFloat64(s._position, s._endian == 0 /* LITTLE_ENDIAN */);
                s.position += 8 /* SIZE_OF_FLOAT64 */;
                return value;
            }
        }
        public readFloat() {let s = this;
            if (s.validate(4 /* SIZE_OF_FLOAT32 */)) {
                var value = s.data.getFloat32(s._position, s._endian == 0 /* LITTLE_ENDIAN */);
                s.position += 4 /* SIZE_OF_FLOAT32 */;
                return value;
            }
        }
        public readInt() {let s = this;
            if (s.validate(4 /* SIZE_OF_INT32 */)) {
                var value = s.data.getInt32(s._position, s._endian == 0 /* LITTLE_ENDIAN */);
                s.position += 4 /* SIZE_OF_INT32 */;
                return value;
            }
        }
        public readShort() {let s = this;
            if (s.validate(2 /* SIZE_OF_INT16 */)) {
                var value = s.data.getInt16(s._position, s._endian == 0 /* LITTLE_ENDIAN */);
                s.position += 2 /* SIZE_OF_INT16 */;
                return value;
            }
        }
        public readUnsignedByte() {let s = this;
            if (s.validate(1 /* SIZE_OF_UINT8 */))
                return s._bytes[this.position++];
        }
        public readUnsignedInt() {let s = this;
            if (s.validate(4 /* SIZE_OF_UINT32 */)) {
                var value = s.data.getUint32(s._position, s._endian == 0 /* LITTLE_ENDIAN */);
                s.position += 4 /* SIZE_OF_UINT32 */;
                return value;
            }
        }
        readUnsignedShort() {let s = this;
            if (s.validate(2 /* SIZE_OF_UINT16 */)) {
                var value = s.data.getUint16(s._position, s._endian == 0 /* LITTLE_ENDIAN */);
                s.position += 2 /* SIZE_OF_UINT16 */;
                return value;
            }
        }
        readUTF() {let s = this;
            var length = s.readUnsignedShort();
            if (length > 0) {
                return s.readUTFBytes(length);
            }
            else {
                return "";
            }
        }
        public readUTFBytes(length) {let s = this;
            if (!s.validate(length)) {
                return;
            }
            var data = s.data;
            var bytes = new Uint8Array(data.buffer, data.byteOffset + s._position, length);
            s.position += length;
            return s.decodeUTF8(bytes);
        }
        public writeBoolean(value) {let s = this;
            s.validateBuffer(1 /* SIZE_OF_BOOLEAN */);
            s._bytes[s.position++] = +value;
        }
        public writeByte(value) {let s = this;
            s.validateBuffer(1 /* SIZE_OF_INT8 */);
            s._bytes[s.position++] = value & 0xff;
        }
        public writeBytes(bytes, offset, length) {let s = this;
            if (offset === void 0) { offset = 0; }
            if (length === void 0) { length = 0; }
            var writeLength;
            if (offset < 0) {
                return;
            }
            if (length < 0) {
                return;
            }
            else if (length == 0) {
                writeLength = bytes.length - offset;
            }
            else {
                writeLength = Math.min(bytes.length - offset, length);
            }
            if (writeLength > 0) {
                s.validateBuffer(writeLength);
                s._bytes.set(bytes._bytes.subarray(offset, offset + writeLength), s._position);
                s.position = s._position + writeLength;
            }
        }
        public writeDouble(value) {let s = this;
            s.validateBuffer(8 /* SIZE_OF_FLOAT64 */);
            s.data.setFloat64(s._position, value, s._endian == 0 /* LITTLE_ENDIAN */);
            s.position += 8 /* SIZE_OF_FLOAT64 */;
        }
        public writeFloat(value) {let s = this;
            s.validateBuffer(4 /* SIZE_OF_FLOAT32 */);
            s.data.setFloat32(s._position, value, s._endian == 0 /* LITTLE_ENDIAN */);
            s.position += 4 /* SIZE_OF_FLOAT32 */;
        }
        public writeInt(value) {let s= this;
            s.validateBuffer(4 /* SIZE_OF_INT32 */);
            s.data.setInt32(this._position, value, this._endian == 0 /* LITTLE_ENDIAN */);
            s.position += 4 /* SIZE_OF_INT32 */;
        }
        public writeShort(value) {let s= this;
            s.validateBuffer(2 /* SIZE_OF_INT16 */);
            s.data.setInt16(s._position, value, s._endian == 0 /* LITTLE_ENDIAN */);
            s.position += 2 /* SIZE_OF_INT16 */;
        }
        public writeUnsignedInt(value) {let s= this;
            s.validateBuffer(4 /* SIZE_OF_UINT32 */);
            s.data.setUint32(s._position, value, s._endian == 0 /* LITTLE_ENDIAN */);
            s.position += 4 /* SIZE_OF_UINT32 */;
        }
        public writeUnsignedShort(value) {let s= this;
            s.validateBuffer(2 /* SIZE_OF_UINT16 */);
            s.data.setUint16(s._position, value, s._endian == 0 /* LITTLE_ENDIAN */);
            s.position += 2 /* SIZE_OF_UINT16 */;
        }
        public writeUTF(value){let s= this;
            var utf8bytes = this.encodeUTF8(value);
            var length = utf8bytes.length;
            s.validateBuffer(2 /* SIZE_OF_UINT16 */ + length);
            s.data.setUint16(s._position, length, s._endian == 0 /* LITTLE_ENDIAN */);
            s.position += 2 /* SIZE_OF_UINT16 */;
            s._writeUint8Array(utf8bytes, false);
        }
        public writeUTFBytes(value) {let s= this;
            s._writeUint8Array(s.encodeUTF8(value));
        }
        public toString() {let s= this;
            return "[ByteArray] length:" + s.length + ", bytesAvailable:" + s.bytesAvailable;
        }
        private _writeUint8Array(bytes, validateBuffer:boolean=true) {let s= this;
            if (validateBuffer === void 0) { validateBuffer = true; }
            var pos = s._position;
            var npos = pos + bytes.length;
            if (validateBuffer) {
                s.validateBuffer(npos);
            }
            s.bytes.set(bytes, pos);
            s.position = npos;
        }
        public validate(len) {let s= this;
            var bl = s._bytes.length;
            if (bl > 0 && s._position + len <= bl) {
                return true;
            }
            else {
                console.log("1025");
            }
        }
        public validateBuffer(len) {let s= this;
            s.write_position = len > s.write_position ? len : s.write_position;
            len += s._position;
            s._validateBuffer(len);
        }
        public encodeUTF8(str) {let s= this;
            var pos = 0;
            var codePoints = s.stringToCodePoints(str);
            var outputBytes = [];
            while (codePoints.length > pos) {
                var code_point = codePoints[pos++];
                if (s.inRange(code_point, 0xD800, 0xDFFF)) {
                    s.encoderError(code_point);
                }
                else if (s.inRange(code_point, 0x0000, 0x007f)) {
                    outputBytes.push(code_point);
                }
                else {
                    var count = void 0, offset = void 0;
                    if (s.inRange(code_point, 0x0080, 0x07FF)) {
                        count = 1;
                        offset = 0xC0;
                    }
                    else if (s.inRange(code_point, 0x0800, 0xFFFF)) {
                        count = 2;
                        offset = 0xE0;
                    }
                    else if (s.inRange(code_point, 0x10000, 0x10FFFF)) {
                        count = 3;
                        offset = 0xF0;
                    }
                    outputBytes.push(s.div(code_point, Math.pow(64, count)) + offset);
                    while (count > 0) {
                        var temp = s.div(code_point, Math.pow(64, count - 1));
                        outputBytes.push(0x80 + (temp % 64));
                        count -= 1;
                    }
                }
            }
            return new Uint8Array(outputBytes);
        }
        public decodeUTF8(data) {let s= this;
            var fatal = false;
            var pos = 0;
            var result = "";
            var code_point;
            var utf8_code_point = 0;
            var utf8_bytes_needed = 0;
            var utf8_bytes_seen = 0;
            var utf8_lower_boundary = 0;
            while (data.length > pos) {
                var _byte = data[pos++];
                if (_byte == s.EOF_byte) {
                    if (utf8_bytes_needed != 0) {
                        code_point = s.decoderError(fatal);
                    }
                    else {
                        code_point = s.EOF_code_point;
                    }
                }
                else {
                    if (utf8_bytes_needed == 0) {
                        if (s.inRange(_byte, 0x00, 0x7F)) {
                            code_point = _byte;
                        }
                        else {
                            if (s.inRange(_byte, 0xC2, 0xDF)) {
                                utf8_bytes_needed = 1;
                                utf8_lower_boundary = 0x80;
                                utf8_code_point = _byte - 0xC0;
                            }
                            else if (s.inRange(_byte, 0xE0, 0xEF)) {
                                utf8_bytes_needed = 2;
                                utf8_lower_boundary = 0x800;
                                utf8_code_point = _byte - 0xE0;
                            }
                            else if (s.inRange(_byte, 0xF0, 0xF4)) {
                                utf8_bytes_needed = 3;
                                utf8_lower_boundary = 0x10000;
                                utf8_code_point = _byte - 0xF0;
                            }
                            else {
                                s.decoderError(fatal);
                            }
                            utf8_code_point = utf8_code_point * Math.pow(64, utf8_bytes_needed);
                            code_point = null;
                        }
                    }
                    else if (!s.inRange(_byte, 0x80, 0xBF)) {
                        utf8_code_point = 0;
                        utf8_bytes_needed = 0;
                        utf8_bytes_seen = 0;
                        utf8_lower_boundary = 0;
                        pos--;
                        code_point = s.decoderError(fatal, _byte);
                    }
                    else {
                        utf8_bytes_seen += 1;
                        utf8_code_point = utf8_code_point + (_byte - 0x80) * Math.pow(64, utf8_bytes_needed - utf8_bytes_seen);
                        if (utf8_bytes_seen !== utf8_bytes_needed) {
                            code_point = null;
                        }
                        else {
                            var cp = utf8_code_point;
                            var lower_boundary = utf8_lower_boundary;
                            utf8_code_point = 0;
                            utf8_bytes_needed = 0;
                            utf8_bytes_seen = 0;
                            utf8_lower_boundary = 0;
                            if (s.inRange(cp, lower_boundary, 0x10FFFF) && !this.inRange(cp, 0xD800, 0xDFFF)) {
                                code_point = cp;
                            }
                            else {
                                code_point = s.decoderError(fatal, _byte);
                            }
                        }
                    }
                }
                //Decode string
                if (code_point !== null && code_point !== s.EOF_code_point) {
                    if (code_point <= 0xFFFF) {
                        if (code_point > 0)
                            result += String.fromCharCode(code_point);
                    }
                    else {
                        code_point -= 0x10000;
                        result += String.fromCharCode(0xD800 + ((code_point >> 10) & 0x3ff));
                        result += String.fromCharCode(0xDC00 + (code_point & 0x3ff));
                    }
                }
            }
            return result;
        }
        public encoderError(code_point) {
            console.log("1026"+ code_point);
        }
        public decoderError(fatal, opt_code_point = 0) {
            if (fatal) {
                console.log("1027");
            }
            return opt_code_point || 0xFFFD;
        }
        public inRange(a, min, max) {
            return min <= a && a <= max;
        }
        public div(n, d) {
            return Math.floor(n / d);
        }
        public stringToCodePoints(string) {let s= this;
            /** @type {Array.<number>} */
            var cps = [];
            // Based on http://www.w3.org/TR/WebIDL/#idl-DOMString
            var i = 0, n = string.length;
            while (i < string.length) {
                var c = string.charCodeAt(i);
                if (!s.inRange(c, 0xD800, 0xDFFF)) {
                    cps.push(c);
                }
                else if (s.inRange(c, 0xDC00, 0xDFFF)) {
                    cps.push(0xFFFD);
                }
                else {
                    if (i == n - 1) {
                        cps.push(0xFFFD);
                    }
                    else {
                        var d = string.charCodeAt(i + 1);
                        if (s.inRange(d, 0xDC00, 0xDFFF)) {
                            var a = c & 0x3FF;
                            var b = d & 0x3FF;
                            i += 1;
                            cps.push(0x10000 + (a << 10) + b);
                        }
                        else {
                            cps.push(0xFFFD);
                        }
                    }
                }
                i += 1;
            }
            return cps;
        }
        /** uncompress需要引用zlib.min.js */
        public uncompress(algorithm="zlib"){let s = this;
            var inflate = new Zlib.Inflate(new Uint8Array(s.buffer));
            var inbuffer = inflate.decompress();
            s.buffer = inbuffer.buffer;
            s._position = 0;
        }

        /** compress需要引用zlib.min.js */
        public compress(algorithm="zlib"){let s = this;
            let deflate = new Zlib.Deflate(new Uint8Array(s.buffer));
            let inbuffer = deflate.compress();
            s.buffer=inbuffer.buffer;
            s._position = 0;
        }
    }

